/*
 * Created by Wildish on 2016-10-28
 *
 * Contact me with keithknight@qq.com
 *
 * Copyright (c) 2016 Wildish
 *
 */
package com.wildish.qcface.util;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;

public class FileUtil {

    /**
     * 压缩图片
     * @param sourceFile    原始文件
     * @param destFile      目标文件
     * @param quality       质量
     */
    public static void compressImage(File sourceFile, File destFile, int quality) {
        try{
            if(!sourceFile.exists()) {
                return;
            }
            if(sourceFile.getAbsolutePath().toLowerCase().endsWith("jpg") || sourceFile.getAbsolutePath().toLowerCase().endsWith("jpeg")) {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = false;
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                options.inDither = true;

                Bitmap bmp = decodeSampledBitmap(sourceFile, 768, 1024);
                if(bmp != null) {
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    bmp.compress(Bitmap.CompressFormat.JPEG, quality, bos);

                    FileOutputStream fos = new FileOutputStream(destFile);
                    fos.write(bos.toByteArray());
                    fos.flush();
                    fos.close();
                } else {
                    FileUtil.copyFileTo(sourceFile,destFile);
                }
            } else {
                FileUtil.copyFileTo(sourceFile,destFile);
            }
        } catch (Exception e) {
            e.printStackTrace();
            FileUtil.copyFileTo(sourceFile, destFile);
        }
    }

    private static Bitmap decodeSampledBitmap(File file, int reqWidth, int reqHeight) {
        try{
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            InputStream is = new FileInputStream(file);
            BitmapFactory.decodeStream(is, null, options);

            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            options.inJustDecodeBounds = false;
            options.inPreferredConfig = Bitmap.Config.RGB_565;
            options.inDither = true;

            InputStream is2 = new FileInputStream(file);
            Bitmap result = BitmapFactory.decodeStream(is2, null, options);

            is.close();
            is2.close();
            return result;
        } catch(Exception e) {
        }
        return null;
    }

    private static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    private static boolean copyFileTo(File srcFile, File destFile) {
        if (srcFile == null)
            return false;
        if (destFile == null)
            return false;
        if (!isFileExists(srcFile)) {
            return false;
        }

        if (!isFile(srcFile)) {
            return false;
        }
        if (isFileExists(destFile) && !isFile(destFile))
            return false;

        File parentFile = destFile.getParentFile();
        if (!createOrExistsFolder(parentFile)) {
            return false;
        }

        FileInputStream fis = null;
        FileOutputStream fos = null;
        boolean result = false;
        try {
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            int readLen = 0;
            byte[] buf = new byte[1024];
            while ((readLen = fis.read(buf)) != -1) {
                fos.write(buf, 0, readLen);
            }
            fos.flush();
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
            result = false;
        } finally {
            try {
                fos.close();
                fis.close();
            } catch (Exception e) {
                e.printStackTrace();
                result = false;
            }

        }
        return result;
    }

    private static boolean isFileExists(File file) {
        if (file == null)
            return false;
        return file.exists();
    }

    private static boolean isFile(File file) {
        if (file == null)
            return false;
        return file.isFile();
    }

    private static boolean createOrExistsFolder(File file) {
        if (file == null)
            return false;
        boolean result = false;

        if (isFileExists(file) && isDirectory(file)) {
            return true;
        }
        if (file.mkdirs()) {
            result = true;
        } else {
            result = false;
        }
        return result;
    }

    private static boolean isDirectory(File file) {
        if (file == null)
            return false;
        return file.isDirectory();
    }
}
